package com.network.retrofit.net;


import android.app.Application;
import android.text.TextUtils;

import com.network.retrofit.net.okhttp.OkHttpUtil;
import com.network.retrofit.utils.NetWorkLogUtil;
import com.trello.rxlifecycle3.LifecycleTransformer;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;

/**
 * 项目创建人:
 * 创建人:fargo(罗)
 * Created by app on 2020/9/14  —————— 16:05
 * 作用: 请求客户端
 * 备注:
 *
 * @author android
 */
public class RetrofitClient {
    private static String TAG = "RetrofitClient";
    private static String TAGXML = "RetrofitClientXML";

    private static class RetrofitClientHolder {
        private static RetrofitClient instance = new RetrofitClient();
    }

    private static RetrofitClient getInstance() {
        return RetrofitClientHolder.instance;
    }

    public static RetrofitClient getService() {
        return getInstance();
    }

    private boolean isDebug = true;
    private OkHttpClient okHttpClient;
    private Retrofit.Builder retrofitBuilderGson;
    private Retrofit.Builder retrofitBuilderXML;
    /**
     * 默认前缀地址
     */
    private String baseUrl;
    /**
     * 必须参数
     */
    private Application application;

    /**
     * 参数类型
     */
    public static enum ParmaType {
        TYPE_GSON,
        TYPE_XML
    }


    /**
     * 初始化方法
     *
     * @param application
     * @return
     */
    public RetrofitClient init(Application application) {
        this.application = application;
        return this;
    }

    /**
     * 用户自己设置okHttpClient
     *
     * @param client
     * @return
     */
    public RetrofitClient setOkHttpClient(OkHttpClient client) {
        this.okHttpClient = client;
        return this;
    }

    /**
     * @param baseUrl
     * @return
     */
    public RetrofitClient setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
        return this;
    }

    /**
     * 设置是否是DEBUG模式
     *
     * @param isDebug
     * @return
     */
    public RetrofitClient setDebug(boolean isDebug) {
        this.isDebug = isDebug;
        return this;
    }


    /**
     * 获取默认的 okHttpClient
     *
     * @return
     */
    public OkHttpClient getOkHttpClient() {
        okHttpClient = OkHttpUtil.getInstance().getOkHttpClient(application);
        return okHttpClient;
    }

    /**
     * 获取Debug状态
     *
     * @return
     */
    public boolean getDebug() {
        return isDebug;
    }

    public <T> T instanceRetrofitGson(Class<T> apiInterface, String... mBaseUrl) {
        try {
            //避免重复构建
            if (retrofitBuilderGson == null) {
                retrofitBuilderGson = new Retrofit.Builder()
                        // 请求方  ← 设置请求客户端okhttpClient
                        .client(okHttpClient == null ? getOkHttpClient() : okHttpClient)
                        // 响应方  → Response的事情  回来
                        // RxJava来处理
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        // Gson 来解析 --- JavaBean
                        .addConverterFactory(GsonConverterFactory.create());
            }
            //设置地址前缀
            String strBaseUrl;
            if (mBaseUrl != null && mBaseUrl.length != 0) {
                strBaseUrl = mBaseUrl[0];
            } else if (!TextUtils.isEmpty(baseUrl)) {
                strBaseUrl = baseUrl;
            } else {
                strBaseUrl = "";
                NetWorkLogUtil.logE(TAG, "没有设置baseUrl，请先设置");
            }
            NetWorkLogUtil.logE(TAG, "baseUrl:" + strBaseUrl);
            retrofitBuilderGson.baseUrl(strBaseUrl);
        } catch (Exception e) {
            e.printStackTrace();
            NetWorkLogUtil.logE("RetrofitClient创建异常", e.toString());
        }

        return retrofitBuilderGson.build().create(apiInterface);
    }


    public <T> T instanceRetrofitXml(Class<T> apiInterface, String... mBaseUrl) {
        try {
            //避免重复构建
            if (retrofitBuilderXML == null) {
                retrofitBuilderXML = new Retrofit.Builder()
                        // 请求方  ← 设置请求客户端okhttpClient
                        .client(okHttpClient == null ? getOkHttpClient() : okHttpClient)
                        // 响应方  → Response的事情  回来
                        // RxJava来处理
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        // Xml 来解析 --- JavaBean
                        .addConverterFactory(SimpleXmlConverterFactory.create());
            }
            //设置地址前缀
            String strBaseUrl;
            if (mBaseUrl != null && mBaseUrl.length != 0) {
                strBaseUrl = mBaseUrl[0];
            } else if (!TextUtils.isEmpty(baseUrl)) {
                strBaseUrl = baseUrl;
            } else {
                strBaseUrl = "";
                NetWorkLogUtil.logE(TAGXML, "没有设置baseUrl，请先设置");
            }
            NetWorkLogUtil.logE(TAGXML, "baseUrl:" + strBaseUrl);
            retrofitBuilderXML.baseUrl(strBaseUrl);
        } catch (Exception e) {
            e.printStackTrace();
            NetWorkLogUtil.logE(TAGXML + "创建异常", e.toString());
        }

        return retrofitBuilderXML.build().create(apiInterface);
    }


    public <T> T instanceRetrofit(Class<T> apiInterface, OkHttpClient okHttpClient, ParmaType parmaType, String... mBaseUrl) {
        Retrofit.Builder retrofitBuilder=null;
        if (parmaType == ParmaType.TYPE_GSON) {
            retrofitBuilder = new Retrofit.Builder()
                    // 请求方  ← 设置请求客户端okhttpClient
                    .client(okHttpClient == null ? getOkHttpClient() : okHttpClient)
                    // 响应方  → Response的事情  回来
                    // RxJava来处理
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    // Gson 来解析 --- JavaBean
                    .addConverterFactory(GsonConverterFactory.create());

        }
        else if (parmaType == ParmaType.TYPE_XML) {
            retrofitBuilder = new Retrofit.Builder()
                    // 请求方  ← 设置请求客户端okhttpClient
                    .client(okHttpClient == null ? getOkHttpClient() : okHttpClient)
                    // 响应方  → Response的事情  回来
                    // RxJava来处理
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    // Xml 来解析 --- JavaBean
                    .addConverterFactory(SimpleXmlConverterFactory.create());

        }

        //设置地址前缀
        String strBaseUrl;
        if (mBaseUrl != null && mBaseUrl.length != 0) {
            strBaseUrl = mBaseUrl[0];
        } else if (!TextUtils.isEmpty(baseUrl)) {
            strBaseUrl = baseUrl;
        } else {
            strBaseUrl = "";
            NetWorkLogUtil.logE(TAG, "没有设置baseUrl，请先设置");
        }
        NetWorkLogUtil.logE(TAG, "baseUrl:" + strBaseUrl);
        retrofitBuilder.baseUrl(strBaseUrl);

        return retrofitBuilder.build().create(apiInterface);
    }


    /**
     * @param <UD>
     * @return
     */
    public static <UD> ObservableTransformer<UD, UD> rxConfig(LifecycleTransformer lifecycleTransformer) {

        return new ObservableTransformer<UD, UD>() {
            @Override
            public ObservableSource<UD> apply(Observable<UD> upstream) {
                return lifecycleTransformer == null ?
                        upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                        : upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).compose(lifecycleTransformer);
            }
        };
    }


    /**
     * @param <UD>
     * @return
     */
    public static <UD> ObservableTransformer<UD, UD> rxConfigFileDown(LifecycleTransformer lifecycleTransformer) {

        return new ObservableTransformer<UD, UD>() {
            @Override
            public ObservableSource<UD> apply(Observable<UD> upstream) {
                return lifecycleTransformer == null ?
                        upstream.subscribeOn(Schedulers.io()).observeOn(Schedulers.io())
                        : upstream.subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).compose(lifecycleTransformer);
            }
        };
    }

}
